package com.example.gobang2.controller;

import com.example.gobang2.game.*;
import com.example.gobang2.model.User;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import java.io.IOException;

@Component
public class GameController extends TextWebSocketHandler {
    @Autowired
    private RoomManager roomManager;
    @Autowired
    private OnlineUserManager onlineUserManager;

    ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        GameReadyResponse response = new GameReadyResponse();
        User user = (User) session.getAttributes().get("user");
        if(user == null){
            response.setOk(false);
            response.setReason("用户尚未登录！");
            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
            System.out.println("[GameController] 用户为空！");
            return;
        }
        Room room = roomManager.getRoomByUserId(user.getUserId());
        if(room==null){
            response.setOk(false);
            response.setReason("玩家未匹配到房间！");
            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
            return;
        }
        System.out.println("[GameController] 玩家："+user.getUsername()+"连接到房间："+room.getRoomId());
        onlineUserManager.enterGameRoom(user.getUserId(), session);

        synchronized (room){
            if(room.getUser1()==null){
                room.setUser1(user);
                room.setWhiteUserId(user.getUserId());
                System.out.println("[GameController] 玩家1："+ user.getUsername()+"准备完成，并作为先手方");
                return;
            }
            if(room.getUser2()==null){
                room.setUser2(user);
                System.out.println("[GameController] 玩家2："+ user.getUsername()+"准备完成!");
                noticeGameReady(room,room.getUser1(),room.getUser2());
                noticeGameReady(room,room.getUser2(),room.getUser1());
                System.out.println("[GameController]玩家发送信息完成！");
                return;
            }
        }
        response.setOk(false);
        String reason = "roomId="+room.getRoomId()+"满了！";
        System.out.println("[GameController]"+reason);
        response.setReason(reason);
        session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
    }

    private void noticeGameReady(Room room, User user1, User user2) throws IOException {
        GameReadyResponse response = new GameReadyResponse();
        response.setOk(true);
        response.setRoomId(room.getRoomId());
        response.setThisUserId(user1.getUserId());
        response.setThatUserId(user2.getUserId());
        response.setWhiteUserId(room.getWhiteUserId());
        response.setMessage("gameReady");
        WebSocketSession session1 = onlineUserManager.getSessionFromGameRoom(user1.getUserId());
        if(session1==null){
            response.setOk(false);
            System.out.println("[GameController] 在通知时发现玩家下线：thisUser"+user1.getUsername());
        }
        session1.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
    }

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        User user = (User) session.getAttributes().get("user");
        if(user==null){
            return;
        }
        Room room = roomManager.getRoomByUserId(user.getUserId());
        String text = message.getPayload();
        //System.out.println("收到消息："+text);
        BackMoveResponse backMoveResponse = new BackMoveResponse();
        if(text.contains("backMove")){
            BackMoveRequest backMoveRequest = objectMapper.readValue(text, BackMoveRequest.class);
            //System.out.println("悔棋请求信息"+backMoveRequest);
            if(room.backMove()){
                backMoveResponse.setOk(true);
                backMoveResponse.setMessage("backMoveSuccess");
                //通知对方
                User thatUser = user==room.getUser1()?room.getUser2():room.getUser1();
                WebSocketSession thatSession = onlineUserManager.getSessionFromGameRoom(thatUser.getUserId());
                if(thatSession!=null){
                    thatSession.sendMessage(new TextMessage(objectMapper.writeValueAsString(backMoveResponse)));
                }
            }else{
                backMoveResponse.setOk(false);
                backMoveResponse.setReason("无法悔棋！");
            }
            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(backMoveResponse)));
        }else
            room.putChess(message.getPayload());
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        User user = (User) session.getAttributes().get("user");
        if(user == null){
            return;
        }
        WebSocketSession exitSession = onlineUserManager.getSessionFromGameRoom(user.getUserId());
        if(exitSession!=session){
            System.out.println("[GameController] 当前会话和用户会话不一致！");
            return;
        }
        System.out.println("[GameController] 玩家"+user.getUsername()+"退出游戏！");
        onlineUserManager.removeGameRoom(user.getUserId());
        noticeThatUserWin(user);
    }

    private void noticeThatUserWin(User user) throws IOException {
        Room room = roomManager.getRoomByUserId(user.getUserId());
        if(room == null){
            System.out.println("[GameController] 房间已经不在了，无需通知！");
            return;
        }
        User thatuser = (user == room.getUser1()? room.getUser2():room.getUser1());
        WebSocketSession session = onlineUserManager.getSessionFromGameRoom(thatuser.getUserId());
        if(session==null){
            System.out.println("[GameController] 玩家已经下线，无需通知！");
        }
        GameResponse response = new GameResponse();
        response.setWinner(thatuser.getUserId());
        response.setUserId(thatuser.getUserId());
        session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
    }

    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        User user = (User) session.getAttributes().get("user");
        if(user == null){
            return;
        }
        WebSocketSession exitSession = onlineUserManager.getSessionFromGameRoom(user.getUserId());
        if(exitSession!=session){
            System.out.println("[GameController] 当前会话和用户会话不一致！");
            return;
        }
        System.out.println("[GameController] 玩家"+user.getUsername()+"连接出错！");
        onlineUserManager.removeGameRoom(user.getUserId());
        noticeThatUserWin(user);

    }
}
